package com.lanou3g.ptp.warning.service.impl;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.lanou3g.ptp.achievement.service.DiaryService;
import com.lanou3g.ptp.entity.*;
import com.lanou3g.ptp.sign.service.SignService;
import com.lanou3g.ptp.task.service.TaskService;
import com.lanou3g.ptp.taskstudent.service.TaskStudentService;
import com.lanou3g.ptp.user.service.UserService;
import com.lanou3g.ptp.vo.Option;
import com.lanou3g.ptp.warning.mapper.TaskWarningPlanMapper;
import com.lanou3g.ptp.warning.mapper.WarningMapper;
import com.lanou3g.ptp.warning.mapper.WarningPlanMapper;
import com.lanou3g.ptp.warning.service.WarningService;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Date;
import java.util.List;

@Service(timeout = 5000)
public class WarningServiceImpl implements WarningService {

    @Autowired
    private WarningMapper warningMapper;
    @Autowired
    private WarningPlanMapper warningPlanMapper;
    @Autowired
    private TaskWarningPlanMapper taskWarningPlanMapper;

    @Reference
    private TaskStudentService taskStudentService;
    @Reference
    private SignService signService;
    @Reference
    private DiaryService diaryService;
    @Reference
    private TaskService taskService;
    @Reference
    private UserService userService;

    @Override
    public PageInfo<WarningPlan> findPlansByType(Integer type, Integer page, Integer size) {
        PageHelper.startPage(page, size);
        List<WarningPlan> warningPlans = warningPlanMapper.findByType(type);
        return new PageInfo<>(warningPlans);
    }

    @Override
    public boolean addPlan(WarningPlan warningPlan) {
        if (warningPlan.getTimesInARow() == 0) {
            warningPlan.setTimesInARow(null);
        }
        if (warningPlan.getTimesPerWeek() == 0) {
            warningPlan.setTimesPerWeek(null);
        }
        if (warningPlan.getTimesInTotal() == 0) {
            warningPlan.setTimesInTotal(null);
        }
        Date now = new Date();
        warningPlan.setCreateTime(now);
        warningPlan.setUpdateTime(now);
        warningPlan.setStatus(0);
        return warningPlanMapper.insert(warningPlan) > 0;
    }

    @Override
    public boolean deletePlanById(Long warningPlanId) {
        return warningPlanMapper.deleteById(warningPlanId) > 0;
    }

    @Override
    public boolean updatePlanById(WarningPlan warningPlan) {
        if (warningPlan.getTimesInARow() == 0) {
            warningPlan.setTimesInARow(null);
        }
        if (warningPlan.getTimesPerWeek() == 0) {
            warningPlan.setTimesPerWeek(null);
        }
        if (warningPlan.getTimesInTotal() == 0) {
            warningPlan.setTimesInTotal(null);
        }
        warningPlan.setUpdateTime(new Date());
        return warningPlanMapper.updateById(warningPlan) > 0;
    }

    @Override
    public WarningPlan findPlanById(Long warningPlanId) {
        return warningPlanMapper.findById(warningPlanId);
    }

    @Override
    public List<Option> options(Integer type) {
        return warningPlanMapper.options(type);
    }

    @Override
    public int insertTaskWarningPlans(List<TaskWarningPlan> taskWarningPlans) {
        int count = 0;
        if (taskWarningPlans != null && taskWarningPlans.size() > 0) {
            count = taskWarningPlanMapper.insertAll(taskWarningPlans);
        }
        return count;
    }

    @Override
    public int deleteTaskWarningPlansByTaskId(Long taskId) {
        return taskWarningPlanMapper.deleteByTaskId(taskId);
    }

    @Override
    public void warn(Long taskId, List<WarningPlan> plans, Long studentId) {
        User student = userService.userById(studentId);
        String studentName = student.getName();
        for (WarningPlan plan : plans) {
            Integer type = plan.getType();
            if (WarningPlan.TYPE_SIGN.equals(type)) {
                int timesInARow = signService.getTimesInARow(taskId, studentId);
                int timesPerWeek = signService.getTimesPerWeek(taskId, studentId);
                int timesInTotal = signService.getTimesInTotal(taskId, studentId);
                if (plan.getTimesInARow() != null && timesInARow >= plan.getTimesInARow()) {
                    Warning warning = new Warning(taskId, type);
                    warning.setStudentId(studentId);
                    warning.setContent(String.format(Warning.CONTENT_SIGN_IN_A_ROW, studentName, timesInARow));
                    addWarning(warning);
                }
                if (plan.getTimesPerWeek() != null && timesPerWeek >= plan.getTimesPerWeek()) {
                    Warning warning = new Warning(taskId, type);
                    warning.setContent(String.format(Warning.CONTENT_SIGN_PER_WEEK, studentName, timesPerWeek));
                    addWarning(warning);
                }
                if (plan.getTimesInTotal() != null && timesInTotal >= plan.getTimesInTotal()) {
                    Warning warning = new Warning(taskId, type);
                    warning.setContent(String.format(Warning.CONTENT_SIGN_IN_TOTAL, studentName, timesInTotal));
                    addWarning(warning);
                }
            }
            if (WarningPlan.TYPE_DIARY.equals(type)) {
                int timesInARow = diaryService.getTimesInARow(taskId, studentId);
                int timesPerWeek = diaryService.getTimesPerWeek(taskId, studentId);
                int timesInTotal = diaryService.getTimesInTotal(taskId, studentId);
                if (plan.getTimesInARow() != null && timesInARow >= plan.getTimesInARow()) {
                    Warning warning = new Warning(taskId, type);
                    warning.setContent(String.format(Warning.CONTENT_DIARY_IN_A_ROW, studentName, timesInARow));
                    addWarning(warning);
                }
                if (plan.getTimesPerWeek() != null && timesPerWeek >= plan.getTimesPerWeek()) {
                    Warning warning = new Warning(taskId, type);
                    warning.setContent(String.format(Warning.CONTENT_DIARY_PER_WEEK, studentName, timesPerWeek));
                    addWarning(warning);
                }
                if (plan.getTimesInTotal() != null && timesInTotal >= plan.getTimesInTotal()) {
                    Warning warning = new Warning(taskId, type);
                    warning.setContent(String.format(Warning.CONTENT_DIARY_IN_TOTAL, studentName, timesInTotal));
                    addWarning(warning);
                }
            }
        }
    }

    private void addWarning(Warning warning) {
        List<Warning> warnings = warningMapper.findExistWarning(warning);
        if (warnings.size() == 0) {
            warningMapper.insert(warning);
        }
    }

    @Override
    public List<WarningPlan> findPlansByTaskId(Long taskId) {
        return warningPlanMapper.findByTaskId(taskId);
    }

    @Override
    public PageInfo<Warning> findWarningsByTeacher(Teacher teacher, Integer page, Integer size) {
        List<Long> taskIds = taskService.findTaskIdsByTeacher(teacher);
        PageHelper.startPage(page, size);
        List<Warning> warnings = warningMapper.findByTaskIds(taskIds);
        return new PageInfo<>(warnings);
    }
}
